package novatel

import (
	"dgo/goutils/gnss"
	"dgo/goutils/utils"
	"time"
)

var (
	oem4_sync_buf        = []byte{0xAA, 0x44, 0x12}
	oem4_max_len  uint16 = 10240 // zjy
)

type NovAtelOem4Decoder struct {
	decodeStep int8
	msgid      uint16
	bodyl      uint16
	cache      utils.BytesBuilder
	week       uint16
	tow        uint32
	/**
	  packBuf 整个包的Buf
	*/
	OnPackage func(msgid uint16, packbuf []byte)
	latest    [gnss.NAVI_SYS_MAX][64][32]gnss.YObsSignal
}

func NewNovAtelOem4Decoder() *NovAtelOem4Decoder {
	rval := &NovAtelOem4Decoder{}
	return rval
}

func (this *NovAtelOem4Decoder) GetWeek() uint16 {
	return this.week
}

func (this *NovAtelOem4Decoder) GetTow() uint32 {
	return this.tow
}

/*
*
包括头+DATA+CRC
*/
func (this *NovAtelOem4Decoder) PackageBuf() []byte {
	return this.cache.Bytes()
}

func (this *NovAtelOem4Decoder) BodyBuf() []byte {
	return this.cache.Buff(28, int(this.bodyl))
}

func (this *NovAtelOem4Decoder) CheckCrc() bool {
	l := this.cache.Len()
	crc0 := gnss.Crc32(this.cache.Buff(0, l-4))
	crc1 := this.cache.Uint32_LE(l - 4)
	return crc0 == crc1
}

func (this *NovAtelOem4Decoder) DecodeHead() {
	this.week = this.cache.Uint16_LE(14)
	this.tow = this.cache.Uint32_LE(16)
}

func (this *NovAtelOem4Decoder) GetGPSTime() time.Time {
	return gnss.TOW2TimeEx(uint(this.week), uint(this.tow))
}

func (this *NovAtelOem4Decoder) CRC() (crc0, crc1 uint32) {
	l := this.cache.Len()
	crc0 = gnss.Crc32(this.cache.Buff(0, l-4))
	crc1 = this.cache.Uint32_LE(l - 4)
	return
}

func (this *NovAtelOem4Decoder) InputByte(v byte) int {
	if this.decodeStep <= 0 {
		this.cache.Reset()
		this.decodeStep = 1
	}

	this.cache.WriteByte(v)
	l := this.cache.Len()
	if this.decodeStep == 1 {
		if l <= len(oem4_sync_buf) {
			idx := l - 1
			if this.cache.Byte(idx) != oem4_sync_buf[idx] {
				this.decodeStep = -1
				return -1
			}
			return 0
		} else if l == 10 { // 长度
			this.bodyl = this.cache.Uint16_LE(8)
			if this.bodyl > oem4_max_len {
				this.decodeStep = -1
				return -1
			}
		} else if l == 28 {
			this.msgid = this.cache.Uint16_LE(4)
			this.decodeStep = 2 // 解码body
		}
	} else if this.decodeStep == 2 {
		if l == 28+int(this.bodyl)+4 {
			if this.OnPackage != nil {
				this.OnPackage(this.msgid, this.cache.Bytes())
			}
			this.decodeStep = 0
			return 1
		}

	}

	return 0
}

func (this *NovAtelOem4Decoder) InputBuf(buf []byte) {
	for i := 0; i < len(buf); i++ {
		this.InputByte(buf[i])
	}

}
